﻿/**
 * TODO task1 faire que les pages utilitaires ne soient plus des pages mais des ajouts dans le dom (pour ne pas changer l'url et même appeler des scripts définis dans cette page)
 * TODO task2 faire que les sons propres à une page ne soient pas interrompus quand on fait un refresh (par exemple prendre le couteau fait une coupure de son). Probablement corrigé avec task1
 * TODO task3 mettre les liens dans les pages utilitaires en agbe_on_click et non onclick
 */

function GameAdversary(id, readerName, imageFile, health, hability) {
    this.id = id;
    this.readerName = readerName;
    this.imageFile = imageFile;
    this.health = health;
    this.hability = hability;
}

function GameObject(id, readerName, imageFile) {
    this.id = id;
    this.readerName = readerName;
    this.imageFile = imageFile;
}

function ObjectEvent(objectId) {

    this.objectId = objectId;
    this.doDefaultBehavior = true;

    this.preventDefaultBehavior = function () {
        this.doDefaultBehavior = false;
    }

    this.isDefaultBehavior = function () {
        return this.doDefaultBehavior;
    }

}

function FightEvent(adversaryId, fightWon) {

    this.adversaryId = adversaryId;
    this.fightWon = fightWon;
    this.doDefaultBehavior = true;

    this.preventDefaultBehavior = function () {
        this.doDefaultBehavior = false;
    }

    this.isDefaultBehavior = function () {
        return this.doDefaultBehavior;
    }

}

var agbe = {
    gameContext:{
        currentPage:'index.html',
        currentGamePage:'index.html',
        currentInventory:new Array(),
        currentHealth:20,
        currentHability:15,
        currentDate:new Date(),
        maxHealth:20,
        worldState:{}
    },
    fightRule:[
        [
            [0, 1000],
            [0, 1000],
            [0, 8],
            [0, 6],
            [1, 6],
            [2, 5],
            [3, 5],
            [4, 5],
            [5, 4],
            [6, 4],
            [7, 4],
            [8, 3],
            [9, 3]
        ],
        [
            [0, 1000],
            [0, 8],
            [0, 7],
            [1, 6],
            [2, 5],
            [3, 5],
            [4, 4],
            [5, 4],
            [6, 3],
            [7, 3],
            [8, 3],
            [9, 3],
            [10, 2]
        ],
        [
            [0, 8],
            [0, 7],
            [1, 6],
            [2, 5],
            [3, 5],
            [4, 4],
            [5, 4],
            [6, 3],
            [7, 3],
            [8, 3],
            [9, 2],
            [10, 2],
            [11, 2]
        ],
        [
            [0, 8],
            [1, 7],
            [2, 6],
            [3, 5],
            [4, 4],
            [5, 4],
            [6, 3],
            [7, 3],
            [8, 2],
            [9, 2],
            [10, 2],
            [11, 2],
            [12, 2]
        ],
        [
            [1, 7],
            [2, 6],
            [3, 5],
            [4, 4],
            [5, 4],
            [6, 3],
            [7, 2],
            [8, 2],
            [9, 2],
            [10, 2],
            [11, 2],
            [12, 2],
            [14, 1]
        ],
        [
            [2, 6],
            [3, 6],
            [4, 5],
            [5, 4],
            [6, 3],
            [7, 2],
            [8, 2],
            [9, 2],
            [10, 2],
            [11, 1],
            [12, 1],
            [14, 1],
            [16, 1]
        ],
        [
            [3, 5],
            [4, 5],
            [5, 4],
            [6, 3],
            [7, 2],
            [8, 2],
            [9, 1],
            [10, 1],
            [11, 1],
            [12, 0],
            [14, 0],
            [16, 0],
            [18, 0]
        ],
        [
            [4, 4],
            [5, 4],
            [6, 3],
            [7, 2],
            [8, 1],
            [9, 1],
            [10, 0],
            [11, 0],
            [12, 0],
            [14, 0],
            [16, 0],
            [18, 0],
            [1000, 0]
        ],
        [
            [5, 3],
            [6, 3],
            [7, 2],
            [8, 0],
            [9, 0],
            [10, 0],
            [11, 0],
            [12, 0],
            [14, 0],
            [16, 0],
            [18, 0],
            [1000, 0],
            [1000, 0]
        ],
        [
            [6, 0],
            [7, 0],
            [8, 0],
            [9, 0],
            [10, 0],
            [11, 0],
            [12, 0],
            [14, 0],
            [16, 0],
            [18, 0],
            [1000, 0],
            [1000, 0],
            [1000, 0]
        ]
    ],
    daysOfWeek:new Array('Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'),
    fightEndListener:undefined,
    objectUsageListener:undefined,
    pageRefreshListener:undefined,
    currentAdversary:undefined,
    generatedElementNumerator:0,
    generatedIdNumerator:0,
    userEventArray:{},
    addHealth:function (delta, doCallEndIfDeath) {
        agbe.gameContext.currentHealth = Math.min(Math.max(0, agbe.gameContext.currentHealth + delta), agbe.gameContext.maxHealth);
        agbe.saveCurrentGameContext();
        if (agbe.gameContext.currentHealth <= 0) {
            if (doCallEndIfDeath == null || doCallEndIfDeath) {
                agbe.endGame("Vous êtes mort.");
            }
        }
    },

    addObjectToInventory:function (objectId) {
        if (!agbe.isInInventory(objectId)) {
            agbe.gameContext.currentInventory.push(objectId);
            agbe.saveCurrentGameContext();
            agbe.refreshPage();
        }
        else {
            agbe.displayUserMessage("You already have this object !");
        }
    },

    addWorldStateProperty:function (property) {
        agbe.getWorldState().push(property);
        agbe.saveCurrentGameContext();
    },

    buildHeaderHtml:function () {
        var result = '<table width="100%">';
        result += '<tr><td rowspan="2">' + agbe.buildTimeMarkup() + '</td><td><a href="#" onclick="agbe.showInventoryPage()" class="ui-link">Objets</a></td><td><a href="#" onclick="agbe.showCharacterPage()" class="ui-link">Santé</a></td><td><a href="#" onclick="agbe.showSavePage()" class="ui-link">Sauvegardes</a></td></tr>';
        var nbObjectsString = 'Aucun objet';
        if (agbe.gameContext.currentInventory.length == 1) {
            nbObjectsString = '1 objet';
        }
        else if (agbe.gameContext.currentInventory.length > 1) {
            nbObjectsString = '' + agbe.gameContext.currentInventory.length + ' objets';
        }
        result += '<tr><td><a href="#" onclick="agbe.showInventoryPage()" class="ui-link">' + nbObjectsString + '</a></td><td><a href="#" onclick="agbe.showCharacterPage()" class="ui-link">' + agbe.gameContext.currentHealth + '/' + agbe.gameContext.maxHealth + '</a></td><td><a href="#" onclick="agbe.showSavePage()" class="ui-link"><img width="30px" height="30px" src="./images/save.png"/></a></td>';
        result += '</tr>';
        result += '</table>';
        return result;
    },

    buildCharacterMarkup:function () {
        var result = 'Votre santé actuelle est de ' + agbe.gameContext.currentHealth + ' sur un maximum de ' + agbe.gameContext.maxHealth;
        return result;
    },

    buildInventoryMarkup:function () {
        var result = '<div class="ui-grid-b">';
        if (typeof(agbe.gameContext.currentInventory) != "undefined" && agbe.gameContext.currentInventory.length > 0) {
            agbe.gameContext.currentInventory.forEach(function (object) {
                var gameObject = agbe.getGameObject(object);
                if (gameObject != null) {
                    result += '<div class="ui-block-a"><img src="images/' + gameObject.imageFile + '" width="100px"/></div><div class="ui-block-b">' + gameObject.readerName + '</div>';
                    result += '<div class="ui-block-c"><div onclick="agbe.fireObjectUsed(\'' + gameObject.id + '\')" class="agbe_button">Utiliser</div>';
                    result += '<div onclick="agbe.fireObjectGiven(\'' + gameObject.id + '\')" class="agbe_button">Donner</div>';
                    result += '<div onclick="agbe.removeObjectFromInventory(\'' + gameObject.id + '\');agbe.refreshInventoryContent();" class="agbe_button">Jeter</div>';
                    result += '</div>'
                }
                else {
                    result += 'No object matches with ' + object + ' id !';
                }
            });
        }
        else {
            result += '<i>Vous n\'avez aucun objet</i>';
        }
        result += '</div>';
        return result;
    },

    buildFightMarkup:function () {
        var result = 'Il faut faire la page pour le monstrer ' + agbe.popParameter('adversaryId');
        return result;
    },

    buildTimeMarkup:function () {
        var result = '';
        result += agbe.daysOfWeek[agbe.gameContext.currentDate.getDay()] + ':';
        if (agbe.gameContext.currentDate.getHours() < 10) {
            result += '0' + agbe.gameContext.currentDate.getHours();
        } else {
            result += agbe.gameContext.currentDate.getHours();
        }
        result += ':';
        if (agbe.gameContext.currentDate.getMinutes() < 10) {
            result += '0' + agbe.gameContext.currentDate.getMinutes();
        } else {
            result += agbe.gameContext.currentDate.getMinutes();
        }
        return result;
    },

    closeFrame:function () {
        agbe.hideComponentsByClass("agbe_frame");
    },

    createHeaderIfNotPresent:function () {
        var $newdiv1 = $('<div id="object1"/>')
        if ($("#agbe_header").length == 0) {
            $('.agbe_page').prepend("<div id='agbe_header' class='ui-header ui-bar-a'><div class='agbe_header_content'>Contenu header</div></div>");
        }
    },

    configureImagesOpacityGivenCurrentTime:function () {
        var lightRatio = agbe.computeLightRatio(agbe.gameContext.currentDate);
        $(".agbe_day").css({ 'opacity':lightRatio });
        $(".agbe_night").css({'opacity':1 - lightRatio });
    },

    computeLightRatio:function (date) {
        var result = 1;
        var hours = date.getHours();
        var minutes = hours * 60 + date.getMinutes();
        if (hours < 12) {
            if (minutes < 180) {
                result = 0;
            }
            else if (minutes < 540) {
                result = (minutes - 180) / 360;
            }
            else {
                result = 1;
            }
        }
        else if (hours >= 12) {
            if (minutes < 900) {
                result = 1;
            }
            else if (minutes < 1260) {
                result = 1 - ((minutes - 900) / 360);
            }
            else {
                result = 0;
            }
        }
        return result;
    },


    displayUserMessage:function (message) {
        agbe.pushParameter('userMessage', message);
        agbe.gotoPage('agbe_message.html');
    },

    doFightRound:function () {
        agbe.playSound('sound/slap.ogg', 2);
        var advHability = agbe.getCurrentAdversary().hability;
        var youHability = agbe.gameContext.currentHability;
        var attackIndex = 6;
        var delta = youHability - advHability;
        if (delta == 0) {
            attackIndex = 6;
        } else if (delta < 0) {
            attackIndex = 6 + Math.max(-6, delta / 2);
        } else if (delta > 0) {
            attackIndex = 6 + Math.min(6, delta / 2);
        }
        var diceRoll = Math.floor((Math.random()*10)+1);
        var hitPoints;
        try {
            hitPoints = agbe.fightRule[diceRoll-1][attackIndex];
        }
        catch (error) {
            alert('error : '+error+' with diceRoll='+diceRoll+' attackIndex='+attackIndex);
        }
        agbe.addHealth(-hitPoints[1], false);
        agbe.getCurrentAdversary().health += -hitPoints[0];
        window.setTimeout(function () {
            agbe.refreshPage();
            agbe.injectVariablesInMarkup();
            var fightEnd = (agbe.getCurrentAdversary().health <= 0 || agbe.gameContext.currentHealth <= 0);
            var fightWon = (fightEnd && agbe.gameContext.currentHealth > 0 );
            if (fightEnd) {
                var fightResultProperty = agbe.popParameter('fightResultProperty');
                if (fightResultProperty) {
                    agbe.getWorldState()[fightResultProperty]=fightWon;
                    agbe.saveCurrentGameContext();
                }
                if (fightWon) {
                    agbe.displayUserMessage('Vous êtes victorieux !');
                }
                else {
                    agbe.endGame('Vous venez d\'être térassé par votre adversaire. Votre aventure se termine ici');
                }
            }
        }, 1600);
    },

    endGame:function (message) {
        agbe.pushParameter('endMessage', message);
        agbe.gotoPage('agbe_end.html');
    },

    fight_getAdversaryEndurance:function () {
        return agbe.getCurrentAdversary().health;
    },

    fight_getAdversaryHability:function () {
        return agbe.getCurrentAdversary().hability;
    },

    fight_getAdversaryName:function () {
        return agbe.getCurrentAdversary().readerName;
    },

    fight_getAdversaryImg:function () {
        return '<img src="images/' + agbe.getCurrentAdversary().imageFile + '" width="95%">';
    },

    fight_getPlayerEndurance:function () {
        return agbe.gameContext.currentHealth + '/' + agbe.gameContext.maxHealth;
    },

    fight_getPlayerHability:function () {
        return agbe.gameContext.currentHability;
    },

    fight_getPlayerName:function () {
        return "Vous";
    },

    fireObjectUsed:function (objectId) {
        var objectEvent = new ObjectEvent(objectId);
        if (!(typeof agbe.objectUsageListener === 'undefined')) {
            agbe.objectUsageListener(objectEvent);
        }
        if (objectEvent.isDefaultBehavior()) {
            agbe.displayUserMessage('Vous ne trouvez aucune utilisation convaincante à cet objet ici.');
        }
    },

    getCurrentAdversary:function () {
        if (typeof agbe.currentAdversary === 'undefined') {
            var advId = agbe.popParameter('adversaryId');
            var go = agbe.contract_returnGameAdversaries();
            for (var i = 0; i < go.length; i++) {
                if (go[i].id == advId) {
                    agbe.currentAdversary = go[i];
                    break;
                }
            }
            if (agbe.currentAdversary == null) {
                alert('impossible to retrieve adversary with id ' + advId);
            }
        }
        return agbe.currentAdversary;
    },

    getCurrentDate:function () {
        return agbe.gameContext.currentDate;
    },

    getGameObject:function (objectId) {
        var result = null;
        var go = agbe.contract_returnGameObjects();
        for (var i = 0; i < go.length; i++) {
            if (go[i].id == objectId) {
                result = go[i];
                break;
            }
        }
        return result;
    },

    getWorldState:function () {
        return agbe.gameContext.worldState;
    },

    gotoPage:function (pageName) {
        window.location = pageName;
    },

    gotoPageAndSpendHours:function (pageName, hourAmount) {
        agbe.spendHours(hourAmount);
        agbe.saveCurrentGameContext();
        agbe.gotoPage(pageName);
    },

    hideComponentsByClass:function (componentsClass) {
        var els = document.getElementsByClassName(componentsClass);
        var elsArray = Array.prototype.slice.call(els, 0);
        elsArray.forEach(function (el) {
            el.style.display = 'none';
        });
    },

    hideComponentsById:function (compId) {
        var el = document.getElementById(compId);
        el.style.display = 'none';
    },

    hideWait:function () {
        $('body').removeClass("loading");
    },

    injectVariablesInMarkup:function () {
        var elementsToBeInjected = $('.agbe_dc');
        for (i = 0; i < elementsToBeInjected.length; i++) {
            var classList = elementsToBeInjected[i].className.split(/\s+/);
            if (classList.length != 2) {
                alert('Impossible to inject variables : elements ' + elementsToBeInjected[i] + ' has incorrect class number');
            }
            else {
                var functionNameToBeEvaluated = classList[1];
                var result = eval(functionNameToBeEvaluated + '()');
                elementsToBeInjected[i].innerHTML = result;
            }
        }
    },

    isInInventory:function (objectId) {
        var result = false;
        if (objectId != null) {
            var objectFound = false;
            var go = agbe.contract_returnGameObjects();
            for (var i = 0; i < go.length; i++) {
                if (go[i].id == objectId) {
                    objectFound = true;
                    break;
                }
            }
            if (objectFound) {
                var objectInInventory = false;
                for (var i = 0; i < agbe.gameContext.currentInventory.length; i++) {
                    if (objectId == agbe.gameContext.currentInventory[i]) {
                        result = true;
                        break;
                    }
                }
            }
            else {
                alert('isInInventory : Impossible to test presence of \'' + objectId + '\' : no object with this id exists !');
            }
        }
        return result;
    },

    isUtilPage:function () {
        var result = false;
        var pattern = '/agbe_.*';
        pattern += '\.html';
        var reg = new RegExp(pattern, "g");
        if (reg.test(agbe.gameContext.currentPage)) {
            result = true;
        }
        return result;
    },

	isWProp:function(property) {
		var propValue = agbe.getWorldState()[property];
		if (propValue == null) {
			return false;
		}
		else {
			return propValue;
		}
	},

    launchFight:function (adversaryId, fightResultProperty) {
        agbe.pushParameter('fightResultProperty',fightResultProperty);
        agbe.showFightPage(adversaryId);
    },

    loadGameIfPossible:function () {
        if (localStorage.getItem("agbe.persistentGameContext") != null) {
            agbe.loadPersistentGameContext();
            agbe.returnToAdventure();
        }
        else {
            agbe.displayUserMessage("Aucune partie n'est actuellement sauvegardée. Chargement impossible.");
        }
    },

    loadPersistentGameContext:function () {
        var jsonString = localStorage.getItem("agbe.persistentGameContext");
        if (jsonString != null) {
            agbe.gameContext = JSON.parse(jsonString);
            agbe.postProcessGameContext();
            agbe.saveCurrentGameContext();
            agbe.gotoPage(agbe.gameContext.currentGamePage);
            agbe.refreshPage();
        }
        else {
            alert('no date found in localStorage.getItem("agbe.persistentGameContext")');
        }
    },

    manageUserEvent:function (event, clickableId) {
        var throwAgbeClick = false;
        if (typeof window.AgbeNative === 'undefined') {
            throwAgbeClick = true;
        }
        else {
            //alert('gestion sur mobile non faite : il faut stocker les evts dans une map par id et quand un touchend arrive sans qu il y ait eu un touchmove, lancer un agbe_click');
            switch (event.type) {
                case 'touchstart':
                    //throwAgbeClick = true;
                    break;
                case 'touchmove':
                    //alert('touch move before pour '+clickableId+'. agbe.userEventArray[clickableId]='+agbe.userEventArray[clickableId]);
                    agbe.userEventArray[clickableId] = true;
                    //alert('touch move after pour '+clickableId+'. agbe.userEventArray[clickableId]='+agbe.userEventArray[clickableId]);
                    break;
                case 'touchend':
                    //alert('touch end before pour '+clickableId+'. agbe.userEventArray[clickableId]='+agbe.userEventArray[clickableId]);
                    if (!agbe.userEventArray[clickableId]) {
                        throwAgbeClick = true;
                    }
                    agbe.userEventArray[clickableId] = false;
                    //alert('touch end after pour '+clickableId+'. agbe.userEventArray[clickableId]='+agbe.userEventArray[clickableId]);
                    break;
            }
        }
        if (throwAgbeClick) {
            var theEvent = document.createEvent('MouseEvents');
            theEvent.initEvent('agbe_click', true, true);
            event.target.dispatchEvent(theEvent);
        }
    },

    returnIdAndGenerateIfNeeded:function (jqueryElement) {
        var attributId = jqueryElement.attr("id");
        if (typeof(attributId) == "undefined") {
            agbe.generatedIdNumerator = agbe.generatedIdNumerator + 1;
            attributId = "agbe_generated_id_" + agbe.generatedIdNumerator;
            jqueryElement.attr("id", attributId);
        }
        return attributId;
    },

    onReady:function () {
        agbe.restoreCurrentGameContext();
        agbe.updateCurrentPage();
        if (!agbe.isUtilPage()) {
            if (typeof window.AgbeNative === 'undefined') {
                $('.agbe_audio_element').each(function () {
                    $(this).get(0).pause();
                    $(this).remove();
                });
            }
            else {
                window.AgbeNative.stopSounds();
            }
        }
        if (!agbe.isUtilPage()) {
            agbe.onGamePageReady();
        }
        else {
            agbe.onUtilPageReady();
        }
        agbe.transformerHtml();
        agbe.refreshPage();
        agbe.saveCurrentGameContext();
        agbe.prepareBody();
        agbe.resizeImages();
        agbe.registerForWindowEvent("resize", agbe.resizeImages);
    },

    onCharacterPageReady:function () {
        agbe.refreshCharacterContent();
    },

    onEndPageReady:function () {
        var endMessage = agbe.popParameter('endMessage');
        $('.agbe_end_content').html(endMessage);
    },

    onFightPageReady:function () {
    },

    onFightPageRefresh:function () {
        if (agbe.gameContext.currentHealth <= 0 || agbe.getCurrentAdversary().health <= 0) {
            $('.agbe_fight_action').html('<h3>Le combat est terminé</h3>');
        }
    },

    onGamePageReady:function () {
        agbe.processCurrentGamePage();
    },

    onInventoryPageReady:function () {
        agbe.refreshInventoryContent();
    },

    onMessagePageReady:function () {
        agbe.refreshMessagePageContent();
    },

    onSavePageReady:function () {
    },

    onSavePagePageShow:function (event, ui) {
        $(ui.prevPage).remove();
    },

    onUtilPageReady:function () {
        if (agbe.gameContext.currentPage.indexOf("/agbe_message.html") > -1) {
            agbe.onMessagePageReady();
        }
        if (agbe.gameContext.currentPage.indexOf("/agbe_inventory.html") > -1) {
            agbe.onInventoryPageReady();
        }
        else if (agbe.gameContext.currentPage.indexOf("/agbe_save.html") > -1) {
            agbe.onSavePageReady();
        }
        else if (agbe.gameContext.currentPage.indexOf("/agbe_end.html") > -1) {
            agbe.onEndPageReady();
        }
        else if (agbe.gameContext.currentPage.indexOf("/agbe_character.html") > -1) {
            agbe.onCharacterPageReady();
        }
        else if (agbe.gameContext.currentPage.indexOf("/agbe_fight.html") > -1) {
            agbe.onFightPageReady();
        }
        agbe.injectVariablesInMarkup();
    },

    onUtilPagePageRefresh:function () {
        if (agbe.gameContext.currentPage.indexOf("/agbe_fight.html") > -1) {
            agbe.onFightPageRefresh();
        }
    },

    onUtilPagePageShow:function (event, ui) {
        if (agbe.gameContext.currentPage.indexOf("/agbe_save.html") > -1) {
            agbe.onSavePagePageShow(event, ui);
        }
    },

    playSound:function (src, iteration) {
        if (typeof window.AgbeNative === 'undefined') {
            agbe.generatedElementNumerator += 1;
            $('body').append('<audio id="' + agbe.generatedElementNumerator + '" class="agbe_audio_element"><source src="' + src + '" type="audio/ogg"/></audio>');
            var numberOfPlay = 0;
            var audioElementJQueryObject = $('#' + agbe.generatedElementNumerator);
            var audioElement = audioElementJQueryObject.get(0);
            audioElement.play();
            audioElementJQueryObject.bind("ended", function () {
                numberOfPlay += 1;
                if (iteration == 0 || numberOfPlay < iteration) {
                    audioElement.play();
                }
            });
        }
        else {
            window.AgbeNative.playSound(src, iteration);
        }
    },

    prepareBody:function () {
    },

    popParameter:function (key) {
        var result = window.localStorage.getItem('agbe.flashParameter.' + key);
        return result;
    },

    postProcessGameContext:function () {
        var dateAsDate = new Date(agbe.gameContext.currentDate);
        agbe.gameContext.currentDate = dateAsDate;
    },

    pushParameter:function (key, value) {
        window.localStorage.setItem('agbe.flashParameter.' + key, value);
    },

    processCurrentGamePage:function () {
        agbe.createHeaderIfNotPresent();
    },

    refreshCharacterContent:function () {
        $('.agbe_character_content').html(agbe.buildCharacterMarkup());
    },

    refreshPage:function () {
        agbe.updateHeader();
        if (agbe.isUtilPage()) {
            agbe.onUtilPagePageRefresh();
        }
        agbe.configureImagesOpacityGivenCurrentTime();
        if (!(typeof agbe.pageRefreshListener === 'undefined')) {
            agbe.pageRefreshListener();
        }
        agbe.hideWait();
        agbe.updateConditionnalContentVisibility();
        $('.ui-page').show();
    },

    refreshMessagePageContent:function () {
        $('.agbe_message_content').html(agbe.popParameter('userMessage'));
    },

    refreshInventoryContent:function () {
        $('.agbe_inventory_content').html(agbe.buildInventoryMarkup());
    },

    registerForWindowEvent:function (eventType, callback) {
        $(window).bind(eventType, callback);
    },

    registerUseObjectCallback:function (callback) {
        agbe.objectUsageListener = callback;
    },

    registerPageRefreshListener:function (callback) {
        agbe.pageRefreshListener = callback;
    },

    removeObjectFromInventory:function (objectId) {
        var index = agbe.gameContext.currentInventory.indexOf(objectId);
        if (index != -1) {
            agbe.gameContext.currentInventory.splice(index, 1);
        }
        agbe.saveCurrentGameContext();
    },

    restartGame:function () {
        agbe.gameContext = agbe.contract_returnNewGameContext();
        agbe.saveCurrentGameContext();
        agbe.gotoPage(agbe.contract_returnHomePage());
    },

    restoreCurrentGameContext:function () {
        var savedData = localStorage.getItem("agbe.currentGameContext");
        if (savedData != null) {
            agbe.gameContext = JSON.parse(savedData);
            agbe.postProcessGameContext();
        }
    },

    restoreButton:function (button) {
        setTimeout(function () {
            $(button).removeAttr("style").hide().fadeIn();
        }, 1000);
    },

    returnToAdventure:function () {
        agbe.restoreCurrentGameContext();
        window.location.href = agbe.gameContext.currentGamePage;
    },

    resizeImages:function () {
        var headerComp = $('#agbe_header');
        var size = headerComp.width();
        var elems = $('.agbe_image_full_width');
        for (i = 0; i < elems.length; i++) {
            elems.eq(i).width(size + 'px');
            elems.eq(i).height('auto');
        }
        elems = $('.agbe_generate_height_spacer');
        for (i = 0; i < elems.length; i++) {
            var id = elems.eq(i).attr('id');
            agbe.updateVerticalSpacer(id);
        }
    },

    saveContext:function (key) {
        var jsonString = JSON.stringify(agbe.gameContext);
        localStorage.setItem(key, jsonString);
    },

    saveCurrentGameContext:function () {
        agbe.saveContext("agbe.currentGameContext");
    },

    savePersistentGameContext:function () {
        agbe.saveContext("agbe.persistentGameContext");
    },

    setWorldState:function (worldState) {
        agbe.gameContext.worldState = worldState;
        agbe.saveCurrentGameContext();
    },

	setWProp:function (property,refreshPage) {
		agbe.getWorldState()[property] = true;
		agbe.saveCurrentGameContext();
		if (refreshPage === true) {
			agbe.refreshPage();
		}
	},

    showFightPage:function (adversaryId) {
        agbe.pushParameter('adversaryId', adversaryId);
        agbe.gotoPage('agbe_fight.html', {role:"dialog"});
    },

    showCharacterPage:function () {
        agbe.gotoPage('agbe_character.html', {role:"dialog"});
    },

    showInventoryPage:function () {
        agbe.gotoPage('agbe_inventory.html', {role:"dialog"});
    },

    showHeader:function () {
        $(".agbe_header_content").show();
    },

    showSavePage:function () {
        agbe.gotoPage('agbe_save.html', {role:"dialog"});
    },

    showWait:function () {
        $('body').addClass("loading");
    },

    spendHours:function (amount) {
        agbe.restoreCurrentGameContext();
        agbe.gameContext.currentDate = new Date(agbe.gameContext.currentDate.getTime() + amount * 3600000);
        agbe.saveCurrentGameContext();
    },

    /**
     * Modifie le html
     */
    transformerHtml:function () {
        // le body
        if (!$('body').hasClass("agbe_already_transformed")) {
            $('body').addClass("ui-mobile-viewport ui-overlay-c agbe_already_transformed");
            $('body').prepend("<div class='modal'></div>");
        }
        // la page
        $('.agbe_page').each(function (index) {
            if (!$(this).hasClass("agbe_already_transformed")) {
                $(this).addClass("ui-page ui-body-c ui-page-active agbe_already_transformed");
            }
        })
        // les boutons
        $('.agbe_button').each(function (index) {
            if (!$(this).hasClass("agbe_already_transformed")) {
                var attributId = agbe.returnIdAndGenerateIfNeeded($(this));
                var contenuBouton = this.innerHTML;
                $(this).html('<span class="ui-btn-inner ui-btn-corner-all"><span class="ui-btn-text">' + contenuBouton + '</span></span>');
                $(this).addClass("ui-btn ui-shadow ui-btn-corner-all ui-btn-up-c agbe_already_transformed");
                var effectScript = document.createElement('script');
                effectScript.type = 'text/javascript';
                var agbe_on_click_content = $(this).attr("agbe_on_click");
                if (typeof(agbe_on_click_content) == "undefined") {
                    agbe_on_click_content = "";
                }
                effectScript.text = '$("#' + attributId + '").bind("touchstart touchmove touchend click",function (event) {agbe.manageUserEvent(event,\'' + attributId + '\')});';
                effectScript.text += '$("#' + attributId + '").bind("agbe_click",function () {$(this).effect("highlight", {}, 500);' + agbe_on_click_content + '});';
                $(this)[0].appendChild(effectScript);
            }
            // les scenes
            $('.agbe_scene').each(function (index) {
                if (!$(this).hasClass("agbe_already_transformed")) {
                    var attributId = agbe.returnIdAndGenerateIfNeeded($(this));
                    $(this).addClass('agbe_generate_height_spacer agbe_already_transformed');
                    var futureInnerHtml = "";
                    var dayImg = $(this).attr('agbe_day');
                    var nightImg = $(this).attr('agbe_night');
                    if (dayImg) {
                        futureInnerHtml += '<img id="day_img_for_' + attributId + '" src="' + dayImg + '" class="agbe_day agbe_image_full_width"/>';
                    }
                    if (nightImg) {
                        futureInnerHtml += '<img src="' + nightImg + '" class="agbe_night agbe_image_full_width"/>';
                    }
                    futureInnerHtml += '<img id="vert_spacer_for_' + attributId + '" src="images/spacer.gif"/>';
                    $(this).html(futureInnerHtml);
                }
            });
        })
    },


    /**
     * Prend en compte l'url de la page courante
     */
    updateCurrentPage:function () {
        agbe.gameContext.currentPage = window.location.pathname;
        if (!agbe.isUtilPage()) {
            agbe.gameContext.currentGamePage = agbe.gameContext.currentPage;
        }
    },

    updateConditionnalContentVisibility : function() {
        $('[agbe_visibility_condition]').each(function() {
            var jsToBeEvaluated = $(this).attr('agbe_visibility_condition');
            var result = eval(jsToBeEvaluated);
            if (!(result === false || result === true)) {
                result = result();
            }
            if (result) {
                $(this).show();
            }
            else {
                $(this).hide();
            }
        });
    },

    updateHeader:function () {
        $('.agbe_header_content').html(agbe.buildHeaderHtml());
        agbe.showHeader();
    },

    updateVerticalSpacer:function (componentId) {
        var realHeight = $('#day_img_for_' + componentId).height();
        if (realHeight > 0) {
            $('#vert_spacer_for_' + componentId).height(realHeight);
        }
        else {
            window.setTimeout(function () {
                agbe.updateVerticalSpacer(componentId)
            }, 100);
        }
    }
};